package main

import (
	"global/libs/ws"
	"time"
	"encoding/json"
	"github.com/ngaut/log"
	"global/constants"
	"global/core"
	"github.com/shopspring/decimal"
	"fmt"
	"strings"
	"global/libs/structs"
	"global/util"
)

type ExchangePair struct {
	Handler  		*Handler
	exit 			chan interface{}

	meta 			*structs.ExchangeBase

	req 			*ws.ExchangePairListRequest

	limit 			int
	slug 			string

	intervalC 		*time.Ticker
}

func (h *ExchangePair) ReadWriteMessage(handler *Handler, message ws.RequestMessage) error {
	h.Handler = handler
	h.handleRequest(message)
	return nil
}

func (h *ExchangePair) handleRequest(message ws.RequestMessage) {
	var req ws.ExchangePairListRequest
	err := json.Unmarshal([]byte(message.Message), &req)
	if err != nil {
		log.Errorf("Error: %s", err)
	}

	if (req.Sort != "amount" && req.Sort != "price" && req.Sort != "percent") ||
		(req.Direction != constants.SortTypeAsc && req.Direction != constants.SortTypeDesc) ||
		req.Exchange == "" {
		h.Handler.response <- ws.ErrorMsg(ws.ErrParameter, constants.RequestExchangePairList)
		return
	}

	if req.Page <= 0 { req.Page = 1 }

	// 判断交易所存不存在
	meta, err := h.getMeta(req.Exchange)
	if err != nil {
		h.Handler.response <- ws.ErrorMsg(ws.ErrExchangeNotExists, constants.RequestExchangePairList)
		return
	}


	h.slug = req.Exchange
	h.meta = meta
	h.limit = req.Page * constants.PageSize

	h.req = &req
	h.getResponse()
}

func (h *ExchangePair) getMeta(exchangeName string) (*structs.ExchangeBase, error) {
	conn := h.Handler.ctx.GetBaseRedis().Get()
	defer conn.Close()


	return core.GetAnalysisExchangeMetaData(conn, exchangeName)
}

func (h *ExchangePair) getResponse()  {
	if h.req == nil {
		return
	}

	conn := h.Handler.ctx.GetBaseRedis().Get()
	defer conn.Close()

	rate, err := core.GetCnyRateByCoin(conn, "usd")
	if err != nil {
		log.Errorf("Error: %s", err)
		return
	}

	rateDecimal, _ := decimal.NewFromString(rate)

	_ = rateDecimal

	vals, err := core.GetAnalysisPairSorted(conn, h.slug, h.req.Sort, h.req.Direction, h.limit)
	if err != nil {
		log.Errorf("Error: %s", err)
		return
	}

	tickers, err := core.GetPairTickersFromExchangeMulti(conn, h.slug, vals)
	if err != nil {
		log.Errorf("Error: %s", err)
	}

	resp := make([]*ws.ExchangeCoinPair, 0)
	for _, t := range tickers {
		from := strings.ToUpper(t.From)
		to := strings.ToUpper(t.To)
		resp = append(resp, &ws.ExchangeCoinPair{
			From: 			from,
			To: 			to,
			Symbol: 		fmt.Sprintf("%s/%s", from, to),
			Volume24h: 		t.Volume,
			Amount24h: 		t.Amount,
			Amount24hUsd: 	t.AmountUsd,
			Amount24hCny: 	t.AmountCny,
			PriceUsd: 		t.PriceUsd,
			PriceCny: 		t.PriceCny,
			Close: 			t.Close,
			Percent: 		t.Percent,
		})
	}

	// get volume
	et, err := core.GetAnalysisExchangeTickerInfo(conn, h.slug)
	if err != nil {
		log.Errorf("Error: %s", err)
		return
	}

	p := &ws.ExchangePairListResponse{
		Data: 		resp,
	}
	p.Meta.NameCn = h.meta.NameCn
	p.Meta.NameEn = h.meta.NameEn
	p.Meta.Logo = util.ImageUrl(h.Handler.ctx.GetImgUrl(), h.meta.Logo)
	p.Total = et.CountPairs
	p.PageSize = constants.PageSize
	p.Page = h.req.Page

	h.Handler.response <- ws.WsResponse(p, constants.RequestExchangePairList)
}

func (h *ExchangePair) Init()  {
	h.req = nil
	h.exit = make(chan interface{})
	h.intervalC = time.NewTicker(2 * time.Second)
	go func() {
		for {
			select {
			case <-h.exit:
				h.intervalC.Stop()
				return
			case <-h.intervalC.C:
				h.getResponse()
			}
		}
	}()
}

func (h *ExchangePair) Clear() {
	h.exit <- true
}